﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
// Copyright (C) 2021 kingerrobot
// 版权所有。 
//
// 文件名：BRcsEquipCrn
// 文件功能描述：
//
// 创建者：名字 (zzl)
// 时间：2021/12/15 8:58:10
//
// 修改人：
// 时间：
// 修改说明：
// 版本：V1.0.0
//----------------------------------------------------------------*/
#endregion
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System;
using System.Data;

namespace KingerRobot.MexicoSailunWMS.SpiService;
public class BRcsEquipCrn : IRcsEquipCrn
{
    private readonly static ITask _Task = new BTask();
    private readonly static ITaskCmd _TaskCmd = new BTaskCmd();

    private readonly static IRcsEquip _RcsEquip = new BRcsEquip();

    public List<CrnForkInfo> GetCrnFork()
    {
        var rcsEquipCrns = GetRcsEquipCrn();
        return GetCrnForkFilter(rcsEquipCrns);
    }

    public PORcsEquipCrn GetCrnForkByFork(long fork)
    {
        var db = Db.Default;
        var result = db.RcsEquipCrns.Where(t => t.CrnFork1 == fork || t.CrnFork2 == fork).FirstOrDefault();
        return result;
    }

    public PORcsEquipCrn GetCrnForkById(long? id)
    {
        var db = Db.Default;
        var result = db.RcsEquipCrns.Where(t => t.Id == id).FirstOrDefault();
        return result;
    }

    public List<PORcsEquipCrn> GetRcsEquipCrn()
    {
        var db = Db.Default;
        var result = db.RcsEquipCrns.ToList();
        return result;
    }

    public List<CrnForkInfo> GetUsableCrnFork(EnumTaskType enumTaskType)
    {
        // 所有可用堆垛机、货叉
        var forks = GetCrnFork();

        // 将正在执行任务标识设为 false
        forks.ForEach(item =>
        {
            item.TaskCount = 0;
            if (item.IsEnable == true)
            {
                //OLDTODO 【已解决】确认都应该是 StartEquip （入库和出库开始设备都是 StartEquip = Fork）
                var taskCmd = _TaskCmd.GetExecutableTaskCmdByEquipId(item.Fork.GetValueOrDefault());
                if (taskCmd != null)
                {
                    item.TaskCount = 1;
                    // 另一只货叉
                    var fork = forks.Where(t => t.IsEnable == true && t.Fork != item.Fork && t.CrnId == item.CrnId).FirstOrDefault();
                    if (fork != null)
                    {
                        fork.TaskCount = item.TaskCount;
                    }
                }
            }
        });

        return forks;
    }

    public List<PORcsEquip> GetBRcsEquips()
    {
        var db = Db.Default;
        var result = db.RcsEquips.Where(f => true).ToList();
        return result;
    }


    /// <summary>
    /// 过滤获取可用的堆垛机和货叉
    /// </summary>
    /// <param name="rcsEquipCrns"></param>
    /// <returns></returns>
    private List<CrnForkInfo> GetCrnForkFilter(List<PORcsEquipCrn> rcsEquipCrns)
    {
        List<CrnForkInfo> pORcsEquipCrns = new();

        var abnormal = _RcsEquip.GetAbnormalEquipAll();

        rcsEquipCrns.ForEach(item =>
        {
            // 一号货叉
            CrnForkInfo crnForkInfo1 = new()
            {
                CrnArea1 = item.CrnArea1,
                CrnArea2 = item.CrnArea2,
                CrnId = item.Id,
                Fork = item.CrnFork1,
                IsEnable = true,
                Index = 1,
            };
            // 二号货叉
            CrnForkInfo crnForkInfo2 = new()
            {
                CrnArea1 = item.CrnArea1,
                CrnArea2 = item.CrnArea2,
                CrnId = item.Id,
                Fork = item.CrnFork2,
                IsEnable = true,
                Index = 2,
            };

            var crn = abnormal.Where(t => t.Id == item.Id).Any();
            if (crn)
            {
                // 堆垛机异常
                crnForkInfo1.IsEnable = false;
                crnForkInfo2.IsEnable = false;

            }
            else
            {
                var fork1 = abnormal.Where(t => t.Id == item.CrnFork1).Any();
                if (fork1)
                {
                    // 货叉异常
                    crnForkInfo1.IsEnable = false;

                }
                var fork2 = abnormal.Where(t => t.Id == item.CrnFork2).Any();
                if (fork2)
                {
                    // 货叉异常
                    crnForkInfo2.IsEnable = false;

                }
            }
            pORcsEquipCrns.Add(crnForkInfo1);
            pORcsEquipCrns.Add(crnForkInfo2);
        });
        return pORcsEquipCrns;
    }
    public List<InOutCountBean> GetInOutCount(InOutCountParam param)
    {
        DbHelper dbHelper = new DbHelper();
        StringBuilder sql = new StringBuilder();
        sql.Append($@"SELECT equips.objid Id,equips.equip_name CrnName,isnull(counts.out_count,0) OutCount, isnull(counts.in_count,0) InCount, rew.warehouse_name HouseName   FROM 
                (SELECT * FROM rcs_equip re WHERE equip_type = 3) as equips LEFT JOIN 
                (select OutC.objid,OutC.equip_name, OutC.out_count, InC.in_count FROM 
                (SELECT re.objid,re.equip_name ,COUNT(*) out_count   FROM bak_wcs_task bwt  	
	                INNER JOIN wcs_equip_loc_hold welh on bwt.start_loc = welh.loc_id and (bwt.task_type = 5 or bwt.task_type=9)   AND bwt.task_status  = 9
	                INNER JOIN rcs_equip re on re.objid = welh.equip_id 
		                WHERE bwt.create_time >= '{param.StartTime}'
		                AND bwt.create_time <= '{param.EndTime}'
	                GROUP by re.equip_name,re.objid ) OutC
                INNER  JOIN 
                (SELECT re.objid,re.equip_name ,COUNT(*) in_count   FROM bak_wcs_task bwt  	
	                INNER JOIN wcs_equip_loc_hold welh on bwt.target_loc  = welh.loc_id and bwt.task_type = 1 AND bwt.task_status = 9
	                INNER JOIN rcs_equip re on re.objid = welh.equip_id 
		                WHERE bwt.create_time >= '{param.StartTime}'
		                AND bwt.create_time <= '{param.EndTime}'
	                GROUP by re.equip_name,re.objid ) InC on OutC.objid = InC.objid) as counts on equips.objid =  counts.objid
	            INNER  JOIN PDB.dbo.rcs_equip_crn crn on equips.objid = crn.objid 
	            INNER JOIN  rcs_equip_warehouse rew on crn.warehouse_id = rew.objid 
	                ORDER BY HouseName;
	
                
        ");

        //var users = table.AsEnumerable().Select(row => new User
        //{
        //    Id = row.Field<int>("Id"),
        //    Name = row.Field<string>("Name"),
        //    Age = row.Field<int>("Age")
        //}).ToList();

        dbHelper.CommandText = sql.ToString();
        dbHelper.CommandType = System.Data.CommandType.Text;

        var r = dbHelper.GetXDataTable();
        if (r is null || r.DataTable is null || r.DataTable.Rows is null || r.DataTable.Rows.Count <= 0) return new();

        var table = r.DataTable;

        
        var list = table.AsEnumerable().Select(row => new InOutCountBean
        {
            CrnName = row.Field<String>("CrnName"),
            OutCount = row.Field<int>("OutCount"),
            InCount = row.Field<int>("InCount"),
            HouseName = row.Field<String>("HouseName")
        }).ToList();
        //List<InOutCountBean> list = new List<InOutCountBean>();
        //for (int i = 0; i < r.DataTable.Rows.Count; i++)
        //{
        //    var entity = r.DataTable.Rows[i].Map<InOutCountBean>();
        //    list.Add(entity);
        //}
        //var result= list.Select(t=>(InOutCountBean)t).ToList();
        return list;
    }


    public List<ScreenCrnBean> GetEquipCrnsByWarehouseId(long WarehouseId)
    {
        DbHelper dbHelper = new DbHelper();
        StringBuilder sql = new StringBuilder();
        var sqlWarehouse = "";
        if (WarehouseId != 0)
        {
            sqlWarehouse = $" and rec.warehouse_id={WarehouseId}";
        }


        sql.Append($@"select equips.equip_name as CrnName,equips.objid,
                       ISNULL(tt1.taskNoA,0)TaskNoA ,tt1.CreateTimeA,ISNULL(tt2.taskNoB,0) TaskNoB,tt2.CreateTimeB,
                       ISNULL(tt3.num,0)as StockCount,ISNULL(tt4.num,0) as EmptyCount,wecn.show_color as ShowColor,wecn.err_msg as ErrMsg,
        wecn.err_end_time as ErrEndTime,
        (select COUNT(1) as inNum from rcs_equip_crn_to_fork rectf inner join wcs_task_cmd  wtc
        on rectf.folk_equip_id=wtc.equip_id
        where wtc.cmd_type=1 and rectf.crn_equip_id=tt4.equip_id ) as InTaskCount,
        (select COUNT(1) as inNum from rcs_equip_crn_to_fork rectf inner join wcs_task_cmd  wtc
        on rectf.folk_equip_id=wtc.equip_id
        where wtc.cmd_type=2  and rectf.crn_equip_id=tt4.equip_id ) as OutTaskCount
           from (SELECT rec.objid,re.equip_name,rew.objid as warehouseId,rew.warehouse_name  FROM rcs_equip_crn rec with(nolock)   
                        inner join rcs_equip re with(nolock) on rec.objid=re.objid 
                        inner join rcs_equip_warehouse rew with(nolock) on rec.warehouse_id = rew.objid 
                        where rec.use_flag=1   {sqlWarehouse} ) as equips
                    left join(select wtc.task_no as taskNoA ,wtc.create_time as createTimeA,rqctf.crn_equip_id from wcs_task_cmd  wtc with(nolock) 
        inner join rcs_equip re with(nolock) on wtc.equip_id=re.objid
                    inner join  rcs_equip_crn_to_fork rqctf with(nolock) 
                            on re.objid=rqctf.folk_equip_id
                            where  cmd_status=2 and cmd_type in(1,2) and re.group_index=1) tt1
                            on equips.objid=tt1.crn_equip_id
                    left join(select wtc.task_no as taskNoB,wtc.create_time as createTimeB,rqctf.crn_equip_id from wcs_task_cmd  wtc with(nolock)  
        inner join rcs_equip re  with(nolock) 
                            on wtc.equip_id=re.objid
                            inner join  rcs_equip_crn_to_fork rqctf 
                            on re.objid=rqctf.folk_equip_id
                            where  cmd_status=2 and cmd_type in(1,2) and re.group_index=2) tt2
                            on equips.objid=tt2.crn_equip_id 
                    left join(select welh.equip_id,COUNT(rl.objid) num from rcs_location rl with(nolock)  inner join wcs_loc_sku wls with(nolock) 
                            on rl.objid=wls.loc_id
                            inner join wcs_equip_loc_hold welh 
                            on rl.objid  = welh.loc_id 
                            where rl.loc_type=33 and rl.loc_has_sku=1 and rl.use_flag=1 
                            group by welh.equip_id)tt3 on  equips.objid=tt3.equip_id
                    left join(select welh.equip_id,COUNT(rl.objid) num from rcs_location rl with(nolock) 
                            inner join wcs_equip_loc_hold welh with(nolock) 
                            on rl.objid  = welh.loc_id 
                            where rl.loc_type=33 and rl.loc_has_sku=0 and rl.use_flag=1 and rl.loc_enable=1 and rl.in_enable=1 
                            group by welh.equip_id)tt4
                            on  equips.objid=tt4.equip_id
                       left join v_equip_crn_node wecn with(nolock)  on  equips.objid=wecn.equip_id");


        dbHelper.CommandText = sql.ToString();
        dbHelper.CommandType = System.Data.CommandType.Text;

        var r = dbHelper.GetXDataTable();
        if (r is null || r.DataTable is null || r.DataTable.Rows is null || r.DataTable.Rows.Count <= 0) return new();

        //使用 LINQ 将 DataTable 转换为 List<User>

        var table = r.DataTable;

        var tables = table.AsEnumerable().Select(row => new  EquipCrnsByWarehouseId

        {
            CrnName = row.Field<string>("CrnName"),
            Objid = row.Field<long>("objid"),
            TaskNoA = row.Field<int>("TaskNoA"),
            CreateTimeA = row.Field<DateTime?>("CreateTimeA"),
            TaskNoB = row.Field<int>("TaskNoB"),
            CreateTimeB = row.Field<DateTime?>("CreateTimeB"),
            StockCount = row.Field<int>("StockCount"),
            EmptyCount = row.Field<int>("EmptyCount"),
            ShowColor = row.Field<string>("ShowColor"),
            ErrMsg = row.Field<string>("ErrMsg"),
            ErrEndTime = row.Field<DateTime?>("ErrEndTime"),
            InTaskCount = row.Field<int>("InTaskCount"),
            OutTaskCount = row.Field<int>("OutTaskCount")
        }).ToList();

        List<ScreenCrnBean> list = new List<ScreenCrnBean>();
        for (int i = 0; i < tables.Count; i++)
        {

            var row = tables[i];
            var entity = new ScreenCrnBean();
            var TaskNoA = row.TaskNoA != 0 ? Convert.ToInt32(row.TaskNoA) : 0;
            var TaskNoB = row.TaskNoB != 0 ? Convert.ToInt32(row.TaskNoB) : 0;
            entity.CrnName = row.CrnName;
            entity.InTaskCount = row.InTaskCount != 0 ? Convert.ToInt32(row.InTaskCount) : 0;
            entity.OutTaskCount = row.OutTaskCount != 0 ? Convert.ToInt32(row.OutTaskCount) : 0;
            entity.TaskNoA = TaskNoA;
            entity.TaskNoB = TaskNoB;
            entity.EmptyCount = row.EmptyCount != 0  ? Convert.ToInt32(row.EmptyCount) : 0;
            entity.StockCount = row.StockCount != 0  ? Convert.ToInt32(row.StockCount) : 0;
            //没有任务的情况下 正常显示 有任务的情况下 如果是默认颜色 则显示有任务的颜色 否则显示反馈颜色
            //entity.ShowColor =  TaskNoA + TaskNoB == 0 ? row.Value("ShowColor") : row.Value("ShowColor") == "Cornsilk" ? "#009100" : row.Value("ShowColor");


            //先判断报警或者手动
            var ErrMsg = row.ErrMsg;
            DateTime? ErrEndTime = !(row.ErrEndTime == null) ? Convert.ToDateTime(row.ErrEndTime) : null;
            if (!String.IsNullOrWhiteSpace(ErrMsg) && ErrEndTime is null)
            {
                if (ErrMsg.Contains("设备状态:手动"))
                {
                    entity.ShowColor = "#00FFFF";
                }
                else
                {
                    entity.ShowColor = "#f43308";
                }

            }
            else
            {
                if (TaskNoA + TaskNoB > 0)
                {
                    if (row.ShowColor == "Cornsilk")
                    {
                        entity.ShowColor = "#009100";
                    }
                    else
                    {
                        entity.ShowColor = row.ShowColor;
                    }
                }
                else
                {
                    entity.ShowColor = row.ShowColor;
                }

            }


            List<DateTime> taskTimelist = new List<DateTime>();
            if (!(row.CreateTimeA == null))
            {
                try
                {
                    var time = Convert.ToDateTime(row.CreateTimeA);
                    taskTimelist.Add(time);
                }
                catch (Exception ex)
                {

                }
            }
            if (!(row.CreateTimeB == null))
            {
                try
                {
                    var time = Convert.ToDateTime(row.CreateTimeB);
                    taskTimelist.Add(time);
                }
                catch (Exception ex)
                {

                }
            }
            entity.TaskTime = taskTimelist.Count > 0 ? taskTimelist.OrderBy(t => t).FirstOrDefault() : null;

            list.Add(entity);
        }

        return list;

    }

    public List<PORcsEquipCrn> GetEquipCrnsByWarehouse(long warehouseId)
    {
        var db = Db.Default;
        var result = db.RcsEquipCrns.Where(t => t.WarehourseId == warehouseId).ToList();
        return result;
    }
}
